home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Bavarian
/
Bavarian #122 (19xx)(APS Electronic).zip
/
Bavarian #122 (19xx)(APS Electronic).adf
/
pascal.dok
< prev
next >
Wrap
Text File
|
1988-08-04
|
57KB
|
1,311 lines
PCQ Version 1.0c
Ein sehr einfacher Pascal Compiler für den Amiga
von Patrick Quaid
PCQ (das steht für Pascal Compiler, Q, tja..., Patrick hat hier einfach
seine Initialien genommen, da er sich keinen Namen ausdenken konnte)
ist ein Subset Compiler, der Assembler Code erzeugt. Er ist nicht
Public Domain (Patrick behält sich das Copyright für den Sourcecode,
den Compiler, den Runtime-Library Sourcecode, die Runtime-Library und
diese Dokumentation vor), kann aber frei verteilt werden, solange alle
Dateien des Archive unverändert beigelegt sind (mit Ausnahme des
Assemblers und des Linkers). Der Compiler ist langsam (meint Patrick)
und beherrscht einige Dinge nicht, aber alles in allem ist er seinen
Preis wert. Zusammenfassend:
Das Schlechte:
Der Compiler ist sehr langsam.
Er erlaubt keine Bereichstypen.
Es unterstützt 'With' und 'Set' nicht.
Der Code ist noch nicht optimiert. Er ist deshalb langsam,
fett und sieht allgemein recht dumm aus.
Der Compiler verkraftet die meisten Fehler nicht besonders gut.
Das Gute:
Er arbeitet zum größtem Teil.
Der Compiler unterstützt Include-Dateien.
Er erlaubt externe Referencen, obwohl sie diese selber überprüfen
müssen (dies ist schließlich nicht Modula-2).
Er unterstützt Records, Zähltypen, Zeiger, Arrays und Strings.
Typen Konvertierungs, wie es sie in Modula-2 (und in Turbo Pascal
ab 4.0, A.d.Ü) gibt, wird ebenfalls unterstützt. Anders ausgedrückt
ist eine Anweisung wie "integer('d')" legal.
Sie können so viele const, var, type procedure und function Blöcke
haben, wie siemöchten.
Er ist kostenlos!
[4mInhaltsverzeichnis
[0m
Dieses Manual ist dafür angelegt, mit einem Dateianzeiger (z.B. MuchMore)
oder einem Texteditor gelesen zu werden, so daß das Inhaltsverzeichnis
statt Seiten- Zeilennummern als Verweise benutzt.
Kapitel Zeilennummer
Wie wird PCQ benutzt? ................................ 129
Eine Erklärung von PCQs Fehlern ...................... 175
Vordefiniertes ....................................... 255
Konstanten .......................................
Typen ............................................
Variablen ........................................
Funktionen .......................................
Prozeduren .......................................
Extra Statements .................................
Die extra Libraries ..............................
Reservierte Wörter ...................................
Fließkomma Mathematik ................................
Die Grenzen von PCQ ..................................
Strings ..............................................
Compiler Direktiven ..................................
Typen Konvertierung ..................................
Externe Verweisen ....................................
Eingabe/Ausgabe ......................................
Fehler ...............................................
Laufzeitfehler .......................................
Quelltexte ...........................................
Bemerkungen für Assembler Programmierer ..............
Geplante Erweiterungen ...............................
Update History .......................................
Weitere Bemerkungen, Copyright & Patricks Addresse ...
[4mWie wird PCQ benutzt?
[0m
Es gibt verschiedene Dateien in diesem Archive (auf der PCQ Diskette,
A.d.Ü), die sie auf ihre Arbeitsdiskette kopieren müssen. Der Compiler
(Pascal) ist natürlich eine davon, ebenso wie die Runtime-Library
(genannt PCQ.Lib - es gibt übrigens eine Readme Datei auf der Diskette,
die alle Dateinamen erklärt; wenn nicht haben sie eine illegale Kopie
und sollten dies Patrick Quaid mitteilen). Wenn sie den Assembler (A68k)
und den Linker (Blink) nicht haben, müssen sie diese auch kopieren
(sie könnten allerdings nicht auf der Diskette sein, sind aber über
Mailbox oder über PD (Fish) leicht erhältlich). Diese Dateien sind
für die einfachsten Compilationen nötig.
Die Dateien mit der Endung ".p" sind Beispielpascalprogramme, die
sie, wenn sie möchten, mitkopieren können. Patrick verbrachte
wesentlich mehr Zeit mit dem Compiler, als mit den Beispielen,
einige sind allerdings interessant, wenn man solche Programme vorher
noch nicht gesehen hat. Sie demonstrieren jede Seite des Compilers,
die Patrick sich vorstellen kann, so daß man sie sich ansehen sollte.
Wenn sie den Quelltext mit dem Compiler erhalten haben, so gibt es
eine Reihe weiterer Dateien mit der Endung ".p".
Die Dateien, die auf ".i" enden, sind Amiga Include Dateien, für
einige der System Libraries. Sie definieren Records, Typen, Konstanten,
Proceduren, Funktionen und Variablen, die man benötigt, um mit dem
System zu arbeiten. Diese sollte man sich ebenfalls irgendwohin
kopieren. Des weiteren gibt es eine Include Datei für einige String
Routinen (sie sind C ähnlich, A.d.Ü). Der Code dieser Routinen ist
in der Runtime-Library.
Wenn sie ein Programm compilieren wollen, müssen sie es erst mit einem
ASCII Texteditor ihrer Wahl (z.B. Dme) schreiben, oder sie benutzen
eines der Beispielprogramme. Dann tippen sie ein:
1> Pascal prog.p prog.asm
"1>" ist das CLI Prompt.
"Pascal" ist der Name des Compilers, den sie, wenn sie möchten beliebig
ändern können. "Prop.p" ist der Pascal-Quelltext, den sie ebenfalls
nennen können, wie sie möchten. Das letzte Wort ist der Name der
Assembler Datei, die erzeugt wird. Zur Zeit sind nur Kommandozeilen-
Optionen erlaubt. Die Beispielprogramme erwarten übrigens, daß die
Include Dateien sich in einem Verzeichnis namens "Include" befinden,
das ein Unterverzeichnis des aktuellen Verzeichnisses ist (anders
gesagt, versuchen die Programme z.B. nicht "exec.i", sondern
"Include/exec.i" einzubinden). Wenn sie hiermit Probleme bekommen,
müssen sie nur die Inlude-Anweisungen am Anfang der Programme ändern.
Wenn die Compilation ohne Fehler endet, müssen sie folgendes eingeben:
1> A68k prog.asm prog.o
Das veranlaßt den Assembler Objetk-Code zu erzeugen. Wenn die Diskette
A68k enthält, so befindet sich höchst wahrscheinlich auch dessen
Dokumentation (A68k.Doc) darauf, so daß sie diese für Informationen
über den Assembler konsultieren müssen. Wenn der Assembler nicht
beigefügt war, versuchen sie sie A68k Version 2.41 von Charlie Gibbs
zu benutzen. A68k macht viele kleine Verbesserungen bei der
Übersetzung und es könnte sein, daß PCQ diese benötigt, so daß Patrick
nicht garantieren kann, daß PCQ mit einem anderem Assembler
zusammenarbeitet. Schließlich müssen sie das Programm noch linken.
Geben sie Folgendes ein:
1> Blink prog.o small.lib to prog library PCQ.lib
Das erzeugt ein lauffähiges Programm namens "Prog".
Alle Pascal Laufzeitroutinen, die Amiga Systemroutinen und Patricks
kleines String-Library sind in PCQ.lib enthalten. Wenn eine der
Routinen ebenso heißt, wie die, die sie benutzen möchten, müssen
sie sie ihre Library oder ihre Objektdatei in der Kommandozeile vor
PCQ.lib schreiben. Wenn Blink sich auf der Diskette befindet, so
befindet sich dessen Dokumentation sicherlich ebenfalls darauf,
so daß sie diese für Antworten auf irgendwelche Fragen lesen müßten.
Patrick benutzt Blink Version 6.7 und auch hier weiß Patrick nicht,
ob PCQ mit einem anderem Linker oder anderen Version arbeiten würde.
Small.lib ist eine Library mit Systemaddressen von Matt Dillon.
Aufgrund eines Fehlers in Blink muß sie als Objektdatei eingebunden
werden und nicht als Library, wo es hingehören würde. Es erhöht die
Größe des Programmes nicht.
Anstelle von den obigen Anweisungen können sie auch die beigefügte
"make" Batchdatei benutzen. Sie müssen es vielleicht an ihre
Verzeichnissstruktur anpassen und anschließend wird es durch die
Fähigkeiten von AmigaDOS 1.3 (oder durch die wesentlich besseren
von ARP 1.3, von der TBAG 31, zu dem sie von der AIT oder von mit
auch eine ausführliche deutsche Anleitung bekommen können)
mittels "Protect make +s" als ausführbare Batchdatei deklariert und
sie müssen nur noch Folgendes eingeben, um einen (fehlerfreien)
Quelltext in ein ausführbares Programm umzuwandeln:
1> make prog
Diese Anweisung nimmt die Datei 'prog.p' und erzeigt die Datei 'prog'.
Wenn ihr Programm separat kompilierte Units (Module, Objektdateien)
hat, müssen sie die Batchdatei modifizieren, z.B. den Linkeraufruf
hinausnehmen und von Hand eingeben. Patrick rät, für jedes Programm,
daß mehrere Male compiliert werden muß, eine Batchdatei zu schreiben.
Wenn sie damit nicht klarkommen können sie an Patrick schreiben
oder ihn anrufen (sie können natürlich auch an micht schreiben oder
anrufen, A.d.Ü).
[4mEine Erklärung von PCQs Fehlern
[0m
Wie oben schon gesagt, arbeiten Sets (set of) und die With Anweisung
nicht. Des weiteren wird folgende Syntax nicht akzeptiert:
type
smallnumber = 1..20;
PCQ prüft nicht auf während der Laufzeit eine Menge überläuft, so daß
die obige Anweiung z.Z. nicht viel bedeuten würde. Die Ausnahme hiervon
sind Arrays, wo eine Bereichsprüfung erfolgt (Näheres siehe unten).
Etwas das auch nicht funktioniert ist Folgendes:
type
WindowPtr = ^Window;
Window = record
NextWindow : WindowPtr;
...
end;
Diese Programm würde in der 2. Zeile mit einem 'Unknown ID' Fehler
abbrechen. Statt dessen müßten sie etwas, das etwa so aussieht,
einsetzen:
type
Window = record
NextWindow : ^Window;
...
end;
WindowPtr = ^Window;
Das ist etwas, das Patrick berichtigen sollte, aber es ist nicht
umbedingt notwendig, so daß ...
(Bei Turbo Pascal würde eine Zuweisung von Window.NextWindow und einer
Variablen des Types WindowPtr einen Typen-Fehler hervorrufen und es
müßte eine Typenumwandlung WindowPtr(Window.NextWindow) erfolgen, A.d.Ü).
Des weiteren benötigt und erlaubt PCQ keine Parameter in der
Programm Kopfzeile. Anders gesagt wäre
Program Texter(input, output);
...nicht erlaubt (dies ist bei den meisten Pascal Compilern so, A.d.Ü).
Sie müssen die Paramter einfach weglassen (Programm Tester;).
Eine weitere Fähigkeit von Standard Pascal, die Patrick nicht umbedingt
einbinden wollte, ist das "goto" Statement. Obwohl sowohl "label", als
auch "goto" reservierte Worte sind, hat Patrick sie noch nicht zu einem
Teil der Sprache gemacht.
Der Compiler erlaubt bisher keine varianten Records. Das wird bald
behoben sein, wahrscheinlich in der nächsten Version des Compilers.
In Arraykonstanten, die Zeichen sind, akzeptiert PCQ nicht die zwei
Hochkommas hintereinander (''), die ein Hochkomma in der Konstanten
darstellen. Stattdessen gibt es einen anderen Type, wozu ich noch
weiter unter komme.
Zum Schluß kommen wir zu verschachtelten Prozeduren. Aufgrund von
zwei Problemen hat Patrick vor längerer Zeit entschieden, sie
wegzulassen, obwohl er einen großteils des Compilers mit der
Absicht geschrieben hat.
Das erste Problem ist das der Namen. Wenn man verschachtelte Prozeduren
in Pascal benutzt, ist es möglich, zwei Prozeduren mit dem selbem
Namen zu haben, die aber in einem unterschiedlichem Level sind.
Das funktioniert mit dem Compiler sehr gut, aber leider hat ein
Assembler nur einen Level. So müßte man verschiedene Namen für die
Prozeduren und Funktionen erzeugen und jeweils die richtige ansprechen.
Das andere Problem ist wesentlich komplexer: aus einer verschachtelten
Prozedur kann man die lokalen Variablen der übergeordneten Prozedur
ansprechen, sowie die eigenen lokalen Variablen, die Parameter und
die globalen Variablen des Programmes. Auch hier ist es kein Problem
des Compilers, aber wenn man ein Programm startet, läuft es nicht
korrekt. Patrick hat den Fehler zwar gefunden, da dessen Behebung mit
Testen aber ziemlich lange dauern würde, hat er diese Version ohne
verschachtelte Prozeduren herausgegeben.
[4mVordefiniertes
[0m
Der Deklarationsteil sieht genauso aus wie in Standard Pascal.
In PCQ kann man jedoch alles beliebig anordnen, und jeden Teil
mehrfach auftreten lassen. Ein Programm könnte z.B. so ausseheh:
Program name:
var
Variablendeklarationen
type
Typen
var
weitere Variablen
procedure
eine Prozedur
var
noch mehr Variablen...
...und so weiter. Trotzdem muß ein Identifier immer noch deklariert
werden, bevor er benutzt werden kann. Patrick erlaubte dies, da es
ziemlich viel arbei ist verschiedene Include Dateien zu deklarieren
(jede der System Inlcude Dateien würde in vie Sektionen unterteilt
werden müssen: die Konstanten, die Typen, die Variablen und die
Prozedure und Funktionen).
CONST
True und False sind als -1 und 0 definiert.
Nil ist als ein Zeiger mit dem konstantem Wert Null deklariert,
es ist aber kein reserviertes Wort, wie in Standard Pascal
An den meisten Stellen, die eine Konstante erwarten, ist
eine Konstanten Berechnung erlaubt, die während des Compilierens
berechnet werden kann (ähnlcih wie in Turbo Pascal 5.0, A.d.Ü).
Das folgende wäre z.B. eine korrekte Anweisung:
const
first = 234;
second = first * 2;
type
thetype = array [first .. first + 7] of char;
Man kann aber Standart Funktionen, Typenumwandlung,
Fließkommazahlen, oder andere Dinge, die man mit Konstanten machen
kann, nicht benutzen. Nur die 5 mathematischen Basicfunktionen
(+, -, *, div, mod) sind bis jetzt möglich. Beachten sie auch,
daß 'first + 7' während des Compilierens berechnet würde, der
selbe Text im Programm aber erst während der Laufzeit (kein
optimierender Linker/Compiler).
Wenn sie Integer Konstanten benutzen, können sie die Stellen mit
einem Unterstrich voneinnander trennen, ählich wie in Ada, z.B.:
const
Tausend = 1_000;
Zehntausen = 1_0_0_0_0;
MaxInt ist als $7FFFFFFF (268435355) definiert.
MaxShort ist 32767, oder $7FFF.
TYPE
Es gibt verschiedene vordefinierte Typen, diese beinhalteten
Folgende:
Integer 4 Bytes, die Länge ist plus oder minus MaxInt
Short 2 Bytes. Buchstaben werden solange als Short
Werte angesehen, bis sie einen größeren Wert als
32767 oder einen kleineren als -32767 annehmen.
Byte 1 Byte. Diese drei Typen sind alle numerischen Typen,
so daß man sie in normalen Zuweisungen benutzen kann,
ohne daß man sich um Konversionen sorgen machen muß.
Der Compiler konvertiert Small Werte automatisch in
die benötigte Größe. Beachten sie, daß es zur Zeit
keine Überlaufsprüfung gibt.
Real 4 Bytes. Diese Zahlen sind im FFP Format (Fließkomma).
Char 1 Byte.
Boolean 1 Byte. False ist 0 und True ist -1
String 4 Bytes. Strings sind nur als ^char definiert.(s.u.)
Address 4 Bytes. Das ist ein Zeiger auf keinen bestimmten Type,
der Typenkompatibel mit jedem anderem Typen ist -
die Konstante NIL ist vom Type Address (der Type Address
entspricht dem Typen Pointer bei Turbo Pascal, A.d.Ü)
Text 18 Bytes. Dies ist nicht dasselbe wie ein 'file of char'
Type. Standard Input und Output sind Text Dateien.
Sie können Integer, Character, Arrays von Charactern und
Strings in Textdateien schreiben und lesen.
Des weiteren können sie Boolean Werte schreiben.
Enumerated 2 Bytes.
Wie oben angegeben, können sie arrays, pointer, records und files,
die auf diesen Typen basieren, benutzen. Sie können auch synonyme
Typen (wie 'type int = integer') benutzen, aber sie sind nicht
sehr konsistent.
Beachten sie auch, daß sie überall, wo sie einen Type benötigen,
auch eine volle Typenbescheibung einsetzen können.
Eine Compiler haben hiermit Probleme und Patrick ist sich nicht
sichern, was Standard Pascal hierfür vorschreibt, aber es
interessiert ihn auch nicht sehr.
VAR
Die einzige standard Variable in PCQ ist:
CommandLine : array [1..128] of char;
Wie der Name angibt, enthält die Variable die CLI Kommandozeile,
mit der das Programm aufgerufen wurde. Sie ist eine Kopie davon,
so daß sie sie nach Eigenbedarf verändern können. Die signifikanten
Zeichen werden von einem Null Byte abgeschlossen, wonach jeder
raten kann, was die Variable enthält. Wenn sie dieses Array nicht
mehr benötigen, können sie es beliebig einsetzen. Es ist vorhanden,
d.h. nimmt Speicherplatz weg, so dß sie es genausogut verplanen
können.
FUNCTION
Die Standart Funktionen, die keinen weiteren transzendenten
Funktionen benötigen, werden unterstütuzt. Dies sind:
function ord ( x : jeder ordinale Type) : intger;
(* gibt den ordinalen Wert eines Argumentes zurück *)
function chr ( x : numerischer Type) : char;
(*gibt ein Zeichen zurück, dessen ASCII Wert eingegeben wurde*)
function abs ( x : real, integer, short oder byte) : dasselbe;
(* gibt den absoluten Wert (ohne Vorzeichen) zurück *)
function succ ( x : ordinaler Type) : dasselbe;
(* gibt x + 1 mit demselbem Type zurück *)
function pred ( x : ordinaler Type) : dasselbe;
(* gibt x - 1 mit demselbem Type zurück *)
function odd ( x : numerischer Type) : boolean;
(* gibt True zurück, wenn der übergebene Wert ungerade ist *)
function trunc ( x : real) : integer;
(* gibt den Integer Teil eines Real Wertes zurück *)
function float ( x : integer, short oder byte) : real;
(* konvertiert diese Tyoen in FFP Format *)
function floor ( x : real) : real;
(* gibt den größten Integer Wert, kleiner als X zurück *)
function ceil ( x . real) : real;
(* git den letzten Integer Wert, größer als x zurück *)
function eof ( x : irgend ein file Type) : boolean;
(* gibt True zurück, wenn sie sich am Ende der Datei befinden*)
function adr ( var x : irgendeine Variable) : Address;
(* gibt die Addresse von X zurück *)
function SizeOf ( t : Name eines Types) : Integer;
(* gibt die Größe eines Types zurück *)
function Bit ( t : integer) : Integer;
(* gibt einen Integer Wert, mit dem angegebenen Bit gesetzt
zurück *)
Außer den FFP Sachen, werden alle Routinen bis zu diesem Punkt
auf die selbe Art und Weise behandelt. Die anderen zwei Standard
Funktionen sind für das öffnen von Dateien. Sie werden vollständig
erklärt, wenn auf die Ein-/Ausgabe eingegangen wird. Es gibt
auch eine Syntax 'typename (expression)', die von der Sprache
unterstützt wird. Es sieht aus wie eine Funktion, ist aber keine
und wird in dem Kapitel über Typenumwandlung erklärt.
PROCEDURE
Die Standard Proceduren sind write, writeln, read, readln, get,
new dispose, exit und trap. Die ersten fünf werden in dem
Ein-/Ausgabe Teil behandelt. Die anderen vier sind:
procedure new ( var x : any pointer variable );
Diese Funktion reserviert Speicher, mit der Größe des Types, auf
den der Zeiger zeigt und übergibt die Addresse an x. PCQ belegt
Speicher, indem es Intuitions AllocRemember() Routinen benutzt,
so daß am Ende des Programmes der Speicher, der mittels new()
belegt wurde, wieder freigegeben wird. Das bedeutet, daß sie
dispose() nicht unbedingt aufrufen müssen, obwohl sie es sollten.
Übrigens bricht das Programm ab, wenn die Belegung nicht
erfolgreich war. Patrick will das eventuell beheben, aber in
der Zwischenzeit können sie mittels Exec Speicher belegen und
die Fehler behandeln, wenn sie es benötigen.
procedure dispose ( var x : pointer variable );
Diese Prozedur gibt belegten Speicher wieder an das System
zurück. Wenn etwas schiefläuft und sie Speicher freigeben wollen,
den sie nie belegt haben, bricht nur die Prozedur, nicht aber
das Programm ab. Das heißt zwar, daß sie vielleicht ein Problem
in ihrem Programm nie bemerken, aber andererseits wird nicht
jedesmal ein GURU hervorgerufen.
procedure exit ( error : integer );
Exit() bricht ein Programm ab. Das ist eine akzetable Methode,
ein Programm zu beenden. Es führt dasselbe aus, das ein Programm
normalerweise bei Beendigung macht und gibt die Fehlernummer,
die sie übergeben, an AmigaDOS. Diese Routinen gibt allen
Belegten Speicher wieder frei und schließt alle Dateien.
Da es die Konventionen erfordern, sollten sie 0 übergeben,
wenn das Programm korekt beendet wurde, 5 für eine Warnung,
10 für einen Fehler und 20 für einen katastrophalen Fehler.
procedure trap ( num : integer );
Der Parameter für diese Funktion muß eine Konstante sein,
obwohl der Type egal ist. Alles was es macht, ist einen
68000 Trap Instruktion in den Code einzufügen. Das ist
nützlich für den Debugger, den Patrick benutzt und für
nichts anderes, das er sich vorstellen kann.
Extra Statements
Erstens unterstützt PCQ if, while, repeat, for und case Anweisungen.
With wird noch nicht unterstützt, aber es wird bald implementiert
werden.
Die if, while und repeat Anweisungen arbeiten so, wie sie es sollen.
Die Case Anweisung ist nun wesentlich mehr wie das normale Pascal
Case als in Version 1.0. Jeder Fall kann nun jede Anzahl von
Konstanten oder Konstantenbereichen haben. Am Ende von Case können
sie ein ELSE Statement angeben, das ausgeführt wird, falls keiner
der anderen Fälle zutraf. Hier sind einige Case Beispiele:
case Letter of case Number * 5 of
'a' : statement1; -MaxInt..0 : statement1;
'b'..'g' : statement2; 1..MaxInt : statement2;
'j', end;
'm'..'o',
'h' : statement3;
else statement4;
end;
Die for Anweisung unterstützt 'downto', das die Steigerung von
1 zu -1 ändert. Es unterstützt außerdem 'by', mit dem man die
Steigerung setzen kann. Das Argument für 'by' kann jeder reguläre
Ausdruck sein, aber für jede negative Steigerung müssen sie 'downto'
anstelle von 'to' benutzen oder die Schleife wird nur einmal
ausgeführt. Alle 'for' Schleifen laufen mindestens einmal durch.
Die Syntax für 'for' sihet ungefähr so aus:
for <Variable> := <Ausdruck> to|downto <Ausdruck>
[by <Ausdruck>] do <Statement>;
Das andere Statement, ds unterstützt wird ist 'return', das einfach
eine Funktion abbricht. Sie können eine Funktion abbrechen, indem
sie ihrem Namen einen Wert zuweisen (Achtung!! - Dies ist in
Turbo Pascal und anderen Dialekten anders ! A.d.Ü.).
Die extra Libraries
Es sollten einige extra Libraries mit auf der Diskette sein, deren
Code in PCQ.lib ist, deren Beschreibungen aber extra sind.
Die meisten dieser Libraries sind Schnittstellen zum Sytem und
alle sind individuell in ihren .i Dateien dokumentiert.
Beachten sie, daß sie, um AmigaDOS, Exec und Intuition Funktionen zu
benutzen, nicht die Libraries öffnen müssen. Alle diese Libraries
werden automatisch vom Startup-Code geöffnent und werden tatsächlich
von allen PCQ Programmen benötigt.
[4mReservierte Wörter
[0m
Die reservierten Wörter von PCQ sind:
and for procedure
array forward program
begin function record
by goto repeat
case if return
const in set
div label then
do mod to
downto not type
else of until
end or var
external packed while
file private with
Wie sie sehen, sind sogar die nicht implementierten Dinge reserviert.
Das einzige, daß nicht in diesem Text erklärt ist, ist "private",
das bei externen Referencen und mehr Flexibiltät in Zukunft helfen soll.
[4mFließkomma Mathematik
[0m
Von Version 1.0c an sind REAL Zahlen in der Sprachen enthalten.
Im Programmtext können sie mittels der der normalen Definition (ABC.DEF)
spezifiert werden. Die wissenschaftliche Syntaxt, z.B. 1.0876E-4, wird
NICHT unterstützt. Die einzigen mathematischen Operanden, die unterstützt
werden, sind +, -, / und *. Der Rest der MathFFP.library ist ebenfalls
ansprechbar. Die Standard Funktionen für Real Zahlen sind Abs(), floor(),
ceil(), trunc() und float().
Funktionen wie sin(), cos() und sqrt() werden nicht von der
MathFFP.library unterstützt. Sie sind in der MathTrans.library enthalten,
die sich auf der Diskette befindet. Daher müssen jedesmal, wenn sie
ein Programm schreiben, daß diese Funktionen verwendet, die
Systemdiskette eingelegt werden, um an das LIBS: Verzeichnis zu kommen.
In MathTrains.i erhalten sie mehr Informationen hierrüber. Patrick hat
keine Pläne, dieses Funktionen zu implementieren. Auf absehbare Zeit
werden sie die MathTrans.library jedesmal für trigonometrische und
exponentiale Funktionen benötigen.
[4mDie Grenzen von PCQ
[0m
Der Compiler akzeptiert Zeilen von jeder Länge, obwohl er bei Fehlern
nur die ersten 128 Zeichen ausgibt. Eine Datei kann bis auf einige
Einschränkungen ebenfalls beliebig groß werden (der Compiler hat
immer nur das akutelle Zeichen im Speicher).
Die erste ist, daß es nur eine begrenzte Anzahl von Identifiern gibt,
da der Compiler sie immer noch in einem großem Array speichert.
Darüber brauche sie sich allerdings keine Sorgen zu machen, da alle
Include Dateiene zusammen gerade einmal ein Drittel des Platzes
einnehmen. Dies wird in der nächsten Version behoben werden.
Es gibt nocht andere Limits, aber Patrick kam niemals auch nur nahe daran
heran, als er den Compiler kompilierte, so daß er sich nicht vorstellen
kann, daß sie sie sie erreichen könnten.
Die zweite Einschränkung ist, daß genug Platz auf der Diskette sein muß,
da der Compiler eine sehr lange Assembler Datei erzeugt.
Der Assembler Code ist normalerweise mehr als fünf mal länger, als der
Pascal Code.
Der Compiler braucht während er läuft mit Stack ca. 220K Speicher.
[4mStrings
[0m
Wie oben angegeben, müssen Strings als '^char' behandelt wreden. Sie
sind so definiert, werden aber auch auch spezielle behandelt. Sie können
dynamisch erstellt, in der Größe verändert und wieder entfernt werden.
Ein String wird mit einem Null Byte am Ende erwartet, was sie beachten
sollten, falls sie eigene String Routinen schreiben, da es sonst Probleme
mit den anderen String Routinen gibt. Im Programmtext, umgeben sie
String mit Anführungszeichen, anstelle der Hochkommas, die normalerweise
in Arrays of Char verwendet werden.
"A string" ; ist ein String, während
'not one' ; als array[1...8] of char angesehen wird.
Eine weitere interessante Fähigkeit von String ist, daß sie mit C
ähnlichen Escape-Sequenzen ausgestattet werden können. Nach einem
Backslash (\) können sie spezielle Zeichen eingeben. C hat davon sehr
viele, aber Patrick hat bisher nur die, die er benutzt, eingefügt:
\n steht für einen Zeilenvorschub oder chr(10)
\t steht für einen Tabulator oder chr(9)
Alle andere wird ungeändert ausgegeben, so daß man hiermit auch
Anführungszeichen in String einfügen kann. Des weiteren muß man es
benutzen, um einen Backslash einzufügen.
"A\tboy\nand\\his \"dog.\"" ; ergibt:
A boy
and\his "dog."
Auf der Diskette befindet sich eine Include Datei namens StringLib.i,
die einige String Routinen deklariert - es sind die, die Patrick für den
Compiler benötigte. Lesen sie die Datei für mehr Informationen. Wenn
sie nicht mit den Strings klarkommen, müssen sie nur daran denken, daß
sie den C Strings sehr ähnlich sind und in dem meisten Situationen
benutzt werden können. Beachten sie, daß sie bei der Deklaration von
Strings keinen Platz für Zeichen bekommen, sondern nur den für die
Addresse des Strings, so daß sie AllocString() aus StringLib oder etwas
ähnliches aufrufen müssen, um Raum zum arbeiten zu erhalten.
Wenn sie ein BASIC Programmierer sind, könnten sie Probleme bekommen
und sollten Literatur über C Strings zu rate ziehen.
Übrigens ist 'stringvar^' vom Type 'char' implememtiert. Die andere
Art, Zeichen eines Strings zu untersuchen, ist die Index Schreibweise.
'S[3]' gibt z.B. das 4. Zeichen im String 'S' zurück, da alle String
Indexe mit Null beginnen.
[4mCompiler Direktiven
[0m
Es wird vielleicht einmal Billionen an Compiler Direktiven geben,
zur Zeit gibt es aber nur Drei. Compiler Direktiven arbeiten
folgendermaßen: Wenn das erste Zeichen in einem Kommentar ein Dollar
Zeichen ($) ist, überprüft der Compiler, ob das nächste Zeichen ein
Befehl ist. Es dürfen zwischen der Klammer, dem Dollar Zeichen und
dem Befehl keine Leerzeichen sein.
Die Compiler Direktiven.
{$I "fname"} Das fügt die Datei "fname" an dieser Stelle in den
Programmtext ein. Wenn dies beendet ist, wird der
Kommentar beendet (hier sind keine weiteren Direktiven
erlaubt) und weitergemacht.
Es kann eine beliebige Anzahl von Leertasten vor dem
Dateinamen und alles was sie wollen dahinter stehen.
Der Dateiname ist ein String, deshalb muß er in
Anführungszeichen eingeschlossen werden. Mehrere der
Beispielprogramme sollten die Include Syntax
demonstrieren.
Ab Version 1.0c haben Include Dateien zwei neue
Möglichkeiten. Die erste ist, daß sie nun verschachtelt
werden können, d.h. eine Include Datei kann in eine
Andere eingebunden wreden. Die zweite Fähigkeit ist, daß
PCQ nun eine Liste der Include Dateien führt, so daß eine
Datei nicht zweimal eingebunden wird. Diese Liste enthält
nur die Dateinamen, nicht Verzeichnisse oder Laufwerke.
{$A Hiermit kann man direkt Assembler Anweisungen in die
Anweisungen Assembler Datei des Compilers schreiben. Sie müssen sich
} die Assembler Ausgabe des Compilers ansehen, um zu
erkenne, wie er Referencen auf Variablen und
Unterprogramme behandelt. Diese Direktive übergibt
einfach alles hinter dem A bis vor der schließenden
Klammer an den Assembler. Sie sollten deshalb auch
Kommentare nach den Assembler Konventionen benutzen.
{$R+} oder Die '+' Anweisung weist dem Compiler an,
{$R-} Bereichsprüfungen für Arrays durchzuführen. Von hier,
bis zu der Stelle, wo {$R-} steht, wird bei jeder Zugriff
auf ein Array überprüft, ob der Index sich im erlaubtem
Rahmen bewegt. Dies vergrößert und verlangsamt das
Programm, deshalb empfiehlt Patrick, es nur in der
Textphase zu benutzen. Wenn ein Index sich außerhalb
seiner Grenzen befindet, wird das Programm mit einer
Fehlermeldung abgebrochen (siehe "Laufzeitfehler" für
weitere Informationen.
[4mTypen Konvertierungn
[0m
Wenn sie Modula-2 (oder Turbo Pascal ab 4.0, A.d.Ü) benutzt haben, können
sie diesen Abschnitt überspringen. Als Patrick den Compiler schrieb,
fand er es nötig, die Typenüberprüfung etwas zu umgehen und benutzte
Modula-2 Syntax, um dies zu erreichen. Wenn sie sie benutzen, wird der
Name eines Types wie eine Funktion eingesetzt. Der Ausdruck in Klammern
wird berechnet und das Ergebnis wird als von dem angegebenem Type
angesehen. Das sieht so aus:
IntegerVariable := integer(irgendein Ordinaler Ausdruck);
CharVar := char (456-450);
if boolena('r') then ...
Das funktioniert sowohl mit den Standardtypen, als auch mit den von
ihnen definierten. Folgendes wäre also auch legal:
type
charprt = ^char;
var
charvar : charprt;
....
charvar := charprt(0);
charvar := charprt(integer(charvar) +1);
Beachten sie, daß die Typen dafür benannt worden sein müssen.
variable := array [1..4] of char(Ausdruck())
würde also nicht arbeiten.
Beachten sie auch, daß nicht alle Typen Konvertierungen funktionieren.
Einen Typen in einen einer anderen Größe konvertieren ist eine genauso
schlechte Idee, wie einen strukturierten Type (Array oder Record)
in einen einfachen umzuwandeln.
[4mExterne Verweise
[0m
Zuerst ein bißchen Hintergrundwissen. Der Quellcode für den Compiler ist
über 79K groß. Das Assemberlistings dazu ist mehr als fünf mal größer,
so daß es wohl in einem Programm zu unübersichtlich geworden wäre. Was
Patrick brauchte, war ein Weg, es zu zerlegen und die Teile einzeln zu
compilieren. Wenn sie eine vorher compilierte Prozedur haben, die
sie aufrufen wollen, müssen sie diese nur vorher deklarieren.
Wenn der Compiler am Ende ihres Programmes die Prozedur nicht gefunden
hat, nimmt er an, daß es eine externe Reference ist und macht
entsprechende Angaben in der Assembler Datei. Das sieht so aus:
procedure DrawMap;
forward;
So lange, wie sie nicht anderes als DrawMap definieren, macht der
Compiler eine externe Reference _DrawMap in die Assembler Datei.
Um die Benutzung von globalen Variablen in externen Routinen zu
ermöglichen, hat Patrick das Dateiformat geändert.
Das normale Dateiformat sieht so aus:
program Name;
Deklarationen
Prozeduren und Funktionen
begin
Hauptprogramm
end.
Die externe Datei sieht so aus:
external;
Deklarationen (wie normal)
Prozeduren und Funktionen (wie normal)
Es gibt drei Dinge zu beachten. Erstens gibt es kein Hauptprogramm,
zweitens keine spezielle Syntax, die das Ende angibt. Als letzte wird
jede Variable, die global deklariert wird, als externe Refernce
betrachtet. Im Quelltext für den Compiler ist eine Datei, in der sich
nur die globalen Deklarationen für den Compiler befinden. Diese Datei
wird von allen 10 Quelltext eingebunden, aber nur das Hauptprogramm
erzeugt Speicherplatz für sie, die anderen 9 nur externe Verweise.
Hier können gleich einige Dinge im Zusammenhang mit dem Assembler
besprochen weerden.
Alle Prozeduren, Funktionen und Variablen Namen werden als externe
Referenzen von dem Modul, in dem sie sind, angeboten. Wenn eine
Routinen daruaf zugreifen will, muß sie nach einem Namen, der mit
einem Unterstrich beginnt und ansonsten mit dem ursprünglichem Namen
identisch ist, suchen. Sie sollten auch geachten, daß keine Prüfung
über Dateien hinweg erfolgt (sie sollten Modula-2 benutzen, wenn sie
das benötigen). Das bedeutet, daß eine Prozedur, die einen String
erwartet, eine Boolean Variaable übergeben bekommt, was wahrscheinlich
einen Guru hervorrufen würde.
Des weiteren sollten sie beachten, daß der Compiler Argumente von
Prozeduren und Funktionen rechts nach links auf dem Stack speichert,
im Gegensatz zu den meisten C Compilern (darunter Lattice C und PDC),
die es andersherum machen. Daß bedeutet nicht, daß sie deren Code und
Libraries nicht benutzen können - es heißt nur, daß sie die Reihenfolge
der Argumente umdrehen müssen.
Noch zwei weitere Bemerkungen: der Compiler die erwarten, daß die
Register d0, d1, d2, a0 und a1 leer sind. D2 könnte ein Problem
sein, aber die Anderen sollten dies nicht. Für weitere Informationen
sollten sie den erzeugten Assembler Code betrachten.
Das Zweite ist, daß sie beachten sollten, ws 'var' vor einer Variable
macht und sollten sicher sein, daß sie dies korrekt benutzen, wenn
sie den Code mit dem anderer Sprachen mischen.
[4mEingabe/Ausgabe
[0m
Es gibt verschiedene Routienen für die Behandlung von IO
(Input/Output = Eingabe/Ausgabe) unter PCQ. Vorher kommt allerdings die
Beschreibung, was passiert, wenn eine Datei geöffnet wird. Die aktuelle
Datei Variable, die sie im Programm deklarieren (ungefähr so:
var
filevar : file of integer;
) ist eine Art Record, der ungefähr so aussähe:
file = record
FileHandle : ein DOS Datei Handler
Buffer : ein Zeiger auf den Eingabe Buffer
Size : die Größe der Elemente in der Datei
EOF : ein Boolean Wert
IN/OUT : (Eingabe/Ausgabe)
NextFle : ein Zeiger auf den nächsten File Record
end;
Sie können diese Felder zwar zur Zeit nocht nicht ansprchen, trotzdem
werden 18 Bytes Speicher reserviert. Wenn sie eine Datei öffnen, werden
alle diese Felder bei Bedarf initialisiert und das erste Element wird in
den Buffer gelesen. Der Buffer wird mittels der filevar^ Syntax
angesprochen. Beachten sie auch, daß das Programm, wenn die Größe der
Elemente größer als 4 oder 3 ist, Speicher für den Buffer reserviert.
Darauf zeigt die Variable Buffer in dem Record. Wenn die Größe 1, 2 oder
4 ist (bei Char, Short oder Integer), benutzt das Programm statt dessen
die Variable Buffer als Buffer, so daß etwas Speicher und Zeit gespart
wird. Filevar^ spricht immer den Buffer an, egal wo er sich befindet.
Im Moment kann der Compiler nur Speicher für ein Dateielement
reservieren, wodurch die Eingabe/Ausgabe des Compilers wesentlich
langsamer wird. Das wird vielleicht eines Tages geändert, zur Zeit
können sie nur auf DOS Routinen zurückgreifen.
Wenn am Ende der Programm Ausführung noch Dateien offen sind, werden
sie vom Shut-Down Code geschlossen. Dies trifft aber nur auf Dateien,
die mit der Pascal Funktion open()geöffnet wurden zu. Alles was sie
direkt durch AmigaDOS öffnen fällt unter ihre eigene Verantwortung.
Die Eingabe/Ausgabe Routinen sind:
function open ( Dateiname : string;
Dateivariable : file of irgendetwas oder Text) : boolean;
(* Diese Funktioe öffnet eine Datei, um sie zu beschreiben. Wenn die
Datei schon existierte, wird sie gelöscht (wie von "rewrite" bei
Turbo Pascal, A.d.Ü.). Wenn alles korrekt war, wird TRUE
zurückgegeben, ansonsten FALSE. *)
function reopen ( Dateiname : string;
filevar : file of irgendetwas oder Text) : boolean;
(* Diese Funktion ist equivalent zu open(), mit der Ausnahme, daß sie
eine schon existierende Datei zum schreiben öffnet (wie "reset" bei
Turbo Pascal, A.d.Ü.). *)
Die übrigen Routinen sind die selben, wie bei den meisten Pascal
Dialekten und werden hier nur der Vollständigkeit halber aufgelistet:
write() Schreibt etwas in eine Datei oder in die Standard Ausgabe
writeln() Macht dasselbe wie write, erzeugt aber einen Zeilenvorschub.
Dies ist nur für Textdateien (auch die Standardausgabe,
A.d.Ü.) sinnvoll.
read() Ließt etwas von einer DAtei oder der Standard Eingabe.
read (filevar, x) ist als
x := filevar^;
get(flevar);
codiert, wie in den meisten Pascal Dialekten.
readln() Ließt Daten bis zu einem Zeilenvorschub (RETURN) ein, was
ebenfalls nur bei Text Datein sinnvoll ist.
get() Ließt das nächste Dateielement aus der Datei in den Buffer.
Wenn der erste Parameter von "read(ln)" oder "write(ln)" eine Variable
ist, wird die Ein-/Ausgabe mit dieser Datei, statt mit der Tastatur
durchgeführt. Das ist normales Pascal und sieht so aus:
writeln(outfile, 'Das Ergebnis ist: ', 56 DIV 4);
Stellenformatierung wird auch wie normal unterstützt:
writeln ((67 * 32) + 5:10);
... gibt das Ergebnis in einem rechts zentriertem Feld mit 10 Stellen
aus, wobei die Zeichen, die den Breich sprengen, links stehen.
Die Anzahl der Stellen kann maximal MaxShort betragen. Sie könne
Stelleformatierung für jeden Type, aber nur in Text Dateien anwenden.
Real Zahlen haben zwei Felder. Das Erste wird genauso wie das für die
Integerzahlen benutz, das Zweite ist nicht nötig und gibt die Anzahl
der Nachkommastellen, die ausgegeben werden sollen, an.
Wenn dies Null ist, werden keine Zahlen und kein Punkt ausgegeben.
Das Maximum hierfür sind 30 STellen, was aber sowie über dem Limit von
FFP liegt. Die Standardeinstellungen hierfür sind write((5.4 / 4.0):1:2).
Der Vollständigkeit halben wird hier noch einmal angegeben, was bei
verschiedenen write Opterationen in eine Text Datei ausgegeben wird:
Write Char
Schreibt ein Zeichen.
Write Boolean
Schreibt TRUE oder FALSE, ohne extra Leerzeichen.
Write Integer
Schreibt die Zahl ohne extra Leerzeichen, aber mit Minus Zeichen.
Write Real
Schreibt den Integer Teil einer Zahl ganz normal und, wenn die
Läänge des zweiten Feldes größer Null ist, einen Punkt, gefolgt
von der Anzahl der Nachkommastellen.
Write Array of Char
Schreibt das ganze Array, vom erstem bis zum letztem Element.
Write String
Schreibt vom erstem Zeichen, bis vor dem Null Byte.
Writeln
Schreibt ein einfaches EOLN (Zeilenende, Chr(10)) Zeichen.
Read Char
Ließt ein Zeichen.
Read Boolean
Ist nicht möglich.
Read Integer
Überspring solange Leerzeichen und Tabulatoren, bis es auf etwas
underes trifft, ließt Stellen, bis es auf etwas anderes trifft.
Wenn die Routinen auf EOLN vor der ersten Stelle trifft, gibt
sie Null zurück. Wenn sie Buchstaben vor Zahlen findet, gibt
sie ebenfalls Null zurück.
Read Real
Ließt den Integer Teil einer Zahl ganz normal und den Zweiten,
falls er vorhanden ist.
Write Array of Char
Ließt solange Array Felder ein, bis das Array voll ist, oder
EOLN kommt. EOLN wird nicht eingelesen, daß müsen sie mit
readln machen. Wenn das Array nicht voll ist, werden die
anderen Felder mit Leerzeichen gefüllt.
Read String
Ließt Zeichen, bis es auf EOLN trifft. Das EOLN Zeichen ist
links (?, A.d.Ü) im Eingabestrom und wird durch ein Null Byte
ersetzt. Beachten sie, daß diese Routine nicht die Länge des
Stringes überprüft, sie müssen sicher sein, daß der String
auch die längste Zeile, auf die er trifft, verarbeiten kann.
Writeln
Ließt Zeichen bis zu und einschließlich dem nächstem EOLN.
Denken sie auch an die Funktion eof(filevar) und beachten sie, daß
es keine put() Funktion analog zu get() gibt. Betrachten sie die
beigefügten Programme für weitere Informatonen. Beachten sie auch,
daß die filevar^ Syntax vorhanden ist. Schauen sie in einen Pascal
Text, um dies zu verstehen (Patrick und ich sind beide der Meinung,
daß turbo Pascal dies nicht benutzt, so daß es Spanisch für die
meisten Pascal Programmier sein wird).
[4mFehler
[0m
Wie oben schon geschrieben, wird der arme Compiler von den meisten
Fehlern völlig verwirrt und fängt an, Fehler auszugeben, die gar nicht
existieren. Eine Reihe von Fehler kann er beheben, z.B. erfolgt bei
Auslassung eines Semikolons trotzdem eine Compilation, mit einer
entsprechenden Fehlermeldung. Sehr wenige andere Fehler werden so gut
verarbeitet. Patrick hofft, den Compiler rin wenug benutzerfreundlicher
zu machen, bis dahin aber wird die Compilation bei 5 Fehlern abgebrochen,
da es sonst passieren könnte, daß der Compiler einen Fehler entdeckt,
daraus weitere Fehler produziert und schließlich an einer Stelle hängen
bleiben würde.
Wenn ein Fehler auftritt, schreibt der Compiler meistens die zwei
Zeilen, die dazu geführt haben und hebt den Teil, an dem er zur Zeit
arbeitet, hervor. Der Fehler trat entweder an der hervorgehobenen Stelle
oder direkt davor auf.
In der nächsten Zeile steht die Zeilennummer des Fehlers und dessen
Erklärung. Im Moment gibt es nur Textbeschreibungen der Fehler, keine
Fehlernummern.
[4mLaufzeitfehler
[0m
Viele Dinge verursachen Laufzeitfehler, aber zur Zeit werden nur einige
unterstützt:
Fehler Erklärung
50 Kein Speicher für new()
52 Array Index außerhalb des erlaubten Bereiches
Die Fehlernummer wird zurückgegeben mittels der exit() Funktion an
AmigaDOS zurückgegeben. Wenn das Programm in einer Batchdatei läuft,
erhalten sie den Rückgabewert. Patrick hofft, das Laufzeitsystem in
der nächsten Version zu verbessern.
[4mQuelltexte
[0m
Patrick schrieb den Compiler aufgrund des Lerneffektes. Hier einige
Stellen, von denen er Informationen bekam:
1. PDC, ein frei vertreibbaren C Compiler von Jeff Lydiatt. Das ist
ein sehr gutes Programm und einer der besten Public Domain Compiler
für den Amiga (der andere sehr gute ist Draco von Chris Gray).
Patrick hat aus den von PDC erzeugten Listings. Der Blick auf den
Assembler Code dieses Compilers war auch Patricks Inspiration, mit
dem Schreiben eines Compilers zu starten.
2. Pascal-S, der Pascal Compiler von ETH Zürich, von dem er einige, aber
nicht viele Gedanken über die Struktur übernahm.
3. Small-C, ein weiterer frei vertreibbarer C Compiler. Dieses ist nicht
annähernd so gut wie PDC, aber seine Einfachheit half Patrick, einige
Dinge zu verstehen. Dieser Compiler und PDC waren die, die Patrick
benutze, bevor PCQ sich selbst compilieren konnte. Viele Aspekte
in der Aufmachung des Compilers stammme von Small-C.
4. Brinch Hansen on Pascal Compilers, von Per Brinch Hasen.
Dieses Buch war nützlicher, als das andere halbe Dutzend, das Patrick
gelesen hat, während er diesen Compiler schrieb. Er hat daraus vieles
über die Dinge, die er falsch machte, gelernt. Großartig.
5. Sozobon-C. Das ist ein Freeware C Compiler für den Atari ST, der
teilweise auf den Amiga übertragen wurde. Patrick hat daraus seine
32 Bit mathematischen Routinen entnommen und überlegt, ob er daraus
noch etwas für Fließkommarechnung übernimmt.
6. Die Toy Compiler Serie in Amiga Transactor von Chris Gray. Patrick
hatte, als er dies schrieb, nur den ersten Teil gelesen, aber Chris,
der Autor von Draco, dessen Hobby es ist, Compiler zu schreiben, hat
viele interessante Dinge in seinem kleinem Compiler gehabt.
Wenn sie Public Domain Compiler mögen, sollten sie sich Draco von
Chris Gray (auf Fish 201) und PDC von Jeff Lydiatt (auf Fish 110)
betrachten. Beide sind bessere Produkte als PCQ (sagt Patrick) und
können sogar mit komerziellen Produkten mithalten. Patrick weiß nicht,
wo sich die neueste Version von PDC befindet, aber sie können ja an
Jeff schreiben, es ist es wert. PDC hat einen vollen Preprozessor,
ein 'cc' Frontend, sehr schnellen optimierten Code ... und arbeitet).
Die Syntax von Draco ist übrigens der von Pascal sehr ähnlich.
[4mBemerkungen für Assembler Programmierer
[0m
Während dem Programmablauf, benutzt PCQ die Register d0, d1, a0 und
a1. Es benutzt auch d2 und d3 für IO Aufrufe und d2, wenn es große
Datenstrukturen vergleicht oder überträgt. D2, D3 und A2 werden alle
von 32 Bit Routinen entfernt. A7 ist wie immer der Stack Zeiger und
a5 wird als Rahmenzeiger benutzt. A6 enthält die Library Addressen,
während eines Systemaufrufes und A4 ist für die Benutzung in der
Zukunft reserviert (um lokale Variablen einer übergeordneten Prozedur
anzusprechen). Die anderen Register sind frei und können von ihnen
benutzt werden. Der Compiler führt keine Codeoptimierung durch.
[4mGeplante Erweiterungen
[0m
Version 1.1 des Compiler wird definitiev Folgendes enthalten:
Volle 32 Bit Mathematik ( Wurde in Version 1.0a ergänzt)
Voll integerierte Fließkommarechnung ( Wurde in Version 1.0c ergänzt)
Implementierung von verschachtelten Prozeduren
Keine weiteren festen Arrays im Compiler selber (Vielleicht nicht...)
Die Möglichkeit, mit der Workbench zu arbeiten ( In Version 1.0a ergänzt).
Ansonsten ist es Patricks Hauptziel, Fehler zu beheben. Ziemlich weit
unten in der Liste steht, jedes Detail von Pascal zu implemetieren.
So weit es geht, möchte Patrick den Compiler über den ARexx Port in
CygnusED Professional einbinden.
Version 1.1 wird wahrscheinlihc im Sommer 89 veröffentlich werden.
Als Patrick dies im July schrieb, war er sich dessen nicht mehr so
sicher, da er wesentlich mehr zu tun hatte, als im Frühling erwartet
(er hat diese Version (1.0c) im Sommer 89 veröffentlicht, A.d.Ü.).
[4mUpdate History
[0m
Version 1.0c, 21 Mai 1989:
Patrick hat die Eingabe Routinen etwas geändert, indem er DOS Dateien
anstelle von PCQ Dateien benutzt. Er hat die Eingabe gepuffert und die
Strukture flexibler gemacht, so daß Eingaben verschachtelt wrden können.
Anstatt einige IfNDef Direktdiven zu implememtieren, hat Patrick eine
Beobachtung der eingebundenen Dateien geschrieben, so daß keine doppelt
eingefügt wird. Die Pufferung der Eingabe hat die Compilierungszeit
halbiert. Patrick hatte nicht geglaubt, daß das so signifikant ist
und überlegt, die Ein-/Ausgabe Routinen unter diesem Aspeckt
zu überdenken.
Er hat eine Überprüfug auf CTRL-C eingefügt, so daß man früh und sauber
abbrechen kann. Die Port.i Include Datei hatte eine Reihe von Fehlern,
die behoben wurden und die Routinen, die ein Consolen Fenster für
Programme öffnen, die eines benötigen, wurden ebenfalls korrigiert.
Vorher gab es Probleme, wenn write() mehere Parameter hatte.
Die SizeOf() Funktion, FLießkommarechnung und die dazugehörigen
Funktionen wurden von Patrick programmiert.
Es gab verschiedene kleinere Probleme mit den Include Dateien, die
Patrick behob, als er die 1.3 Dateien bekam, das erste offizielle
Set, daß er seit Version 1.0 hatte.
Er lockerte die Syntax von AND, OR und NOT, so daß nun Ordinale Typen
erlaubt sind, so daß man nun auch bitweise Operationen mit diesen
Typen durchführen kann. Des weiteren wurde die Funktion Bit()
hinzugefügt.
Schließlich wurden Indexe für Strings eingeführt. Während Patrick dies
machte, fand er einen Fehler in der Addressierungsroutinen selector(),
weshalb er diese neu schrieb. Patrick meint zwar, daß jetzt größerer
Code erzeugt wird, aber er will bald Expression Trees (was immer das
sein mag) einführen.
Version 1.0b, 17. April 1989:
Patrick hat einen Fehler im Vergleich von komplexen Strukturen behoben.
Es scheint, daß vorher zu viele Bytes erwartet wurden, so daß der
Vergleich oft mißlang.
Version 1.0a, 8. April 1989:
In dieser Version wurde 32 Bit Mathematik ergänzt und Fehler in Case
behoben. Für den Mathematik Teil hat Patrick nur den richtigen Assmbler
Quelltext benötigt, aber Case hat er komplett geändert.
Version 1.0 erzeugt eine Tabelle, in der sequentiell nach dem angegebenem
Wert gesucht wurde. Patrick dachte, daß alle Compiler dies so machen,
aber als er ein Turbo Pascal programm debuggte, bemerkte er, daß es
einfach eine Reihe von Vergleichen vor jedem Statement waren.
Patrick meint zwar, das das sehr simpel ist, hat es aber übernommen,
da das, was für Turbo Pascal gut ist, auch für PCQ reicht.
Das nächste, was geändert wurde, ist der Startup Code. Sie können nun
PCQ Programme von der Workbench starten. Das war einerseits eine Frage
der Workbench Message, andererseit von Ein-/Ausgabe. Wenn sie versuchen,
in einem über die Workbench gestartetem Programm etwas über die Standard
Ein-/Ausgabe zu lesen/schreiben, öffnet der Laufzeitcode ein Fenster
für sie.
Des weiteren wurde ein Fehler behoben: Ein Array Index, das bisher nicht
von einem numerischer Typen war, erzeugte Chaos. Jetzt nicht mehr!
Version 1.0, 1. Februar 1989
Die Original Veröffentlichung
[4mWeitere Bemerkungen, Copyright & Patricks Addresse
[0m
Wie oben angegeben sind der Quelltext für den Compiler, der Compiler
selber, der Quelltext für die Runtime Library und die Runtime Library
selber alle (ähem):
Copyright (c) 1989 Patrick Quaid.
Das Packet darf frei vertrieben werdem, solange sich alle Dateien
dieses Archives mit Ausnahme des Assemblers und des Linkers
(legen sie sie aber wenn möglich trotzdem bei) unverändert darin
befinden. Niemand darf mit dem Vertrieb Geld verdienen, d.h. es
darf nur auf Diskette vertrieben werden, bei denen eine vernünftige
Gebühr für die Diskette selber erhoben wird. Eine vernünftige Gebühr
sieht Patrick als $10 pro Diskette an.
Sie können mit dem Quelltext frei herumexerimentieren. Wenn sie
entscheidene Veränderungen machen, würde Patrick sich freuen, wenn sie
sie ihm zustellen, so daß er sie in der nächsten Version einfügen
kann. Wenn sie Verbesserungen machen, die nicht mit den Standard Pascal
Richtlinien übereinstimmen, sollen sie ihr Programm nicht unter dem
Namen PCQ verteiben, da daß nur zu Chaos führt.
Das ist kein Shareware Packet. Die einzige Bezahlung, die Patrick
verlangt, ist eine Mittelung über entdeckte Fehler (nicht über
nicht implementierte Fähigkeiten - die kennt Patrick selber).
Wenn sie unbedingt ihr Geld loswerden wollen, können sie eine
Gebühr an Charlie Gibbs, der den Assembler schrieb, und an
The Software Distillery, die den Linker schrieb, schicken.
Alle Fragen, Kommentare oder was auch immer, könne an folgende
Addresse geschickt werden:
Pat Quaid
8320 E.Redwing
Scottsdale, AZ 85253
(602) 948-8325
Viel Spaß mit dem Compiler. Wenn sie sich über ihn ärgern, bedenken
sie, was sie für ihn bezahlt haben!